#include "serverhandler.hh"

ServerHandler::ServerHandler()
{
    _address = "127.0.0.1";
    _port = 4242;
    _id = (int)inet_addr(_address.c_str()) + _port;
    _threadNumber = 0;
}

ServerHandler::ServerHandler(string address, int port)
{
    _address = address;
    _port = port;
    _id = (int)inet_addr(_address.c_str()) + _port;
    _threadNumber = 0;
}

Socket *ServerHandler::Connect()
{
    Socket *connection;

    if (IsRunning() == false)
        return (0);

    connection = new Socket(Socket::TCP4, _address, _port);

    return (connection);
}

int ServerHandler::GetId()
{
    return (_id);
}

void ServerHandler::Start()
{
    if (!(createThread(&server_handler_starter, (void*)this)))
        cerr << "ServerHandler cannot create main thread!" << endl;
}

void ServerHandler::Stop()
{
    setRunning(false);
    if (false == joinThread())
        destroyThread();
}

void ServerHandler::loop()
{
    int tmp;

    if (!init() || !_server.RecvConnectionConfirmation())
        setRunning(false);
    else
        setRunning(true);
    while (IsRunning())
    {
        if (false == _server.sendCode(PING))
        {
            cerr << "DISPATCHER: Error while sending code to server!" << endl;
            setRunning(false);
        }
        tmp = _server.RecvCode();
        cout << "SERVER [" << _address << ":" << _port << "] has now " << tmp << " clients!" << endl;
        setClientNumber(tmp);
        sleep(1);
    }
    cerr << "DISPATCHER: Server ping connection aborted!" << endl;
}

bool ServerHandler::init()
{
    _network = Socket(Socket::TCP4, _address, _port);

    _network.connect();
    _server.InitDispatcher(&_network);

    return (true);
}

bool ServerHandler::IsRunning()
{
    bool tmp;

    lock();
    tmp = _run;
    unlock();
    return (tmp);
}

void ServerHandler::setRunning(bool run)
{
    lock();
    _run = run;
    unlock();
}

void ServerHandler::setClientNumber(int number)
{
    lock();
    _threadNumber = number;
    unlock();
}

int ServerHandler::GetClientNumber()
{
    int tmp;

    lock();
    tmp = _threadNumber;
    unlock();

    return (tmp);
}

void *server_handler_starter(void *data)
{
    ServerHandler *classInstance = reinterpret_cast<ServerHandler*>(data);
    classInstance->loop();
    return (data);
}
